package com.lemon.cloud.admin.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.amazonaws.services.s3.model.S3Object;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lemon.cloud.admin.entity.SysFile;
import com.lemon.cloud.admin.mapper.SysFileMapper;
import com.lemon.cloud.admin.service.SysFileService;
import com.lemon.cloud.admin.vo.FileVO;
import com.lemon.cloud.comm.model.ResultMsg;
import com.lemon.cloud.minio.OssProperties;
import com.lemon.cloud.minio.service.OssTemplate;
import com.lemon.cloud.minio.util.FileUtils;
import com.lemon.cloud.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

@Service
@Slf4j
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {

    @Autowired
    private OssProperties ossProperties;

    @Autowired
    private OssTemplate ossTemplate;

    @Value("${spring.application.name}")
    private String applicationName;

    @Override
    public ResultMsg<FileVO> uploadFile(MultipartFile file) {
        String fileName = FileUtils.generateFileName(file.getOriginalFilename());
        FileVO vo = new FileVO();
        vo.setBucketName(ossProperties.getBucketName());
        vo.setFileName(fileName);
        vo.setUrl(String.format("/"+applicationName+"/file/%s/%s", ossProperties.getBucketName(), fileName));

        try {
            //业务服务器上传至minio，走的内网，只会有部分影响
            ossTemplate.putObject(ossProperties.getBucketName(), fileName, file.getContentType(),
                    file.getInputStream());
            saveFileLog(file, fileName);
        } catch (Exception e) {
            log.error("上传失败", e);
            return ResultMsg.resultFail(e.getLocalizedMessage());
        }
        return ResultMsg.resultSuccess(vo);
    }

    @Override
    public void getFile(String bucket, String fileName, HttpServletResponse response) {
        try (S3Object s3Object = ossTemplate.getObject(bucket, fileName)) {
            response.setContentType("application/octet-stream; charset=UTF-8");
            IoUtil.copy(s3Object.getObjectContent(), response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件读取异常: {}", e.getLocalizedMessage());
        }
    }

    @Override
    public Boolean delFile(Long id) {
        SysFile file = this.getById(id);
        ossTemplate.removeObject(file.getBucketName(), file.getFileName());
        return this.removeById(id);
    }

    @Override
    public String onlineFile(String bucket, String fileName) {
        return ossTemplate.getObjectURL(bucket, fileName, Duration.of(7, ChronoUnit.DAYS));
    }

    private void saveFileLog(MultipartFile file, String fileName) {
        SysFile sysFile = new SysFile();
        sysFile.setFileName(fileName);
        sysFile.setOriginal(file.getOriginalFilename());
        sysFile.setFileSize(file.getSize());
        sysFile.setType(FileUtil.extName(file.getOriginalFilename()));
        sysFile.setBucketName(ossProperties.getBucketName());
        sysFile.setCreateBy(SecurityUtils.getUser().getUsername());
        sysFile.setUpdateBy(SecurityUtils.getUser().getUsername());
        sysFile.setCreateTime(LocalDateTime.now());
        sysFile.setUpdateTime(LocalDateTime.now());
        this.save(sysFile);
    }
}
